package cn.iocoder.yudao.framework.websocket.config;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.websocket.core.UserHandshakeInterceptor;
import cn.iocoder.yudao.framework.websocket.core.WebSocketChannelInterceptor;
import cn.iocoder.yudao.framework.websocket.core.YudaoWebSocketHandlerDecorator;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * WebSocket 自动配置
 *
 * @author xingyu4j
 */
@AutoConfiguration
// 允许使用 yudao.websocket.enable=false 禁用websocket
@ConditionalOnProperty(prefix = "yudao.websocket", value = "enable", matchIfMissing = true)
@EnableWebSocket
@EnableWebSocketMessageBroker
@EnableConfigurationProperties(WebSocketProperties.class)
public class YudaoWebSocketAutoConfiguration implements WebSocketMessageBrokerConfigurer{
    @Resource
    private WebSocketProperties webSocketProperties;

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {

        String appEndPoint =  StrUtil.addPrefixIfNot(webSocketProperties.getAppEndPoint(),"/");
        // List<String> brokers = webSocketProperties.getBrokers();
        List<String> brokers = webSocketProperties.getBrokers().stream()
                .map(s -> StrUtil.addPrefixIfNot(s,"/"))
                .collect(Collectors.toList());
        String[] brokersArray = ArrayUtil.toArray(brokers, String.class);
        if(webSocketProperties.isRelayEnable()){
            registry.enableStompBrokerRelay(brokersArray).setRelayHost(webSocketProperties.getRelayHost()).setRelayPort(webSocketProperties.getRelayPort())
                    .setClientLogin(webSocketProperties.getClientLogin()).setClientPasscode(webSocketProperties.getClientPassword())
                    .setSystemLogin(webSocketProperties.getClientLogin()).setSystemPasscode(webSocketProperties.getClientPassword());
        }else{
            registry.enableSimpleBroker(brokersArray);
        }
        registry.setApplicationDestinationPrefixes(appEndPoint);
        registry.setUserDestinationPrefix(StrUtil.addPrefixIfNot(webSocketProperties.getUserEndPoint(),"/"));
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        String endPoint =  StrUtil.addPrefixIfNot(webSocketProperties.getEndPoint(),"/");
        registry.addEndpoint(endPoint).setAllowedOriginPatterns("*").addInterceptors(new UserHandshakeInterceptor());
    }
    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(new WebSocketChannelInterceptor());
    }
    @Override
    public void configureWebSocketTransport( WebSocketTransportRegistration registration) {
        /*
         * 1. setMessageSizeLimit 设置消息缓存的字节数大小 字节
         * 2. setSendBufferSizeLimit 设置websocket会话时，缓存的大小 字节
         * 3. setSendTimeLimit 设置消息发送会话超时时间，毫秒
         */
        registration.setMessageSizeLimit(10240)
                .setSendBufferSizeLimit(10240)
                .setSendTimeLimit(100000).addDecoratorFactory(YudaoWebSocketHandlerDecorator::new);
    }
}
